import { defineStore } from 'pinia'
import { ref, reactive, computed } from 'vue'
import { authAPI } from '@/api/auth.js'
import { userAPI } from '@/api/user.js'

export const useUserStore = defineStore('user', () => {
  // 状态
  const isLoggedIn = ref(false)
  // 优先 localStorage，其次 sessionStorage
  const getTokenFromStorage = () => {
    return localStorage.getItem('token') || sessionStorage.getItem('token') || ''
  }
  const token = ref(getTokenFromStorage())
  const userInfo = reactive({
    id: null,
    username: '',
    nickname: '',
    avatarUrl: '',
    email: '',
    status: 'offline',
    level: 1,
    experience: 0,
    totalGames: 0,
    winRate: 0,
    ranking: null,
    bestStreak: 0,
    joinDate: null
  })

  // 安全解码 JWT（不校验签名，仅用于读取 claims）
  const decodeJwt = (jwt) => {
    try {
      if (!jwt || typeof jwt !== 'string' || jwt.split('.').length < 2) return null
      const base64Url = jwt.split('.')[1]
      const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/')
      const jsonPayload = decodeURIComponent(atob(base64).split('').map(c =>
        '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
      ).join(''))
      return JSON.parse(jsonPayload)
    } catch { return null }
  }

  // 当本地存在真实 token 时，用 token claims 立刻同步 userInfo，避免旧的模拟/历史数据干扰
  const syncUserFromTokenClaims = () => {
    const t = token.value || getTokenFromStorage()
    const claims = decodeJwt(t)
    if (!claims) return
    
    const sub = claims.sub || claims.nameid || claims.nameId || null
    const uname = claims.unique_name || claims.username || claims.name || ''
    
    // 完全重置 userInfo，清除任何历史模拟数据
    Object.assign(userInfo, {
      id: sub || null,
      username: uname || '',
      nickname: uname || '',
      avatarUrl: '',
      email: '',
      status: 'online',
      level: 1,
      experience: 0,
      totalGames: 0,
      winRate: 0,
      ranking: null,
      bestStreak: 0,
      joinDate: null
    })
    
    // 仅根据 token 设置登录态为 true，后续仍会通过后端校验完善资料
    if (t && sub) isLoggedIn.value = true
  }

  // 计算属性
  const isAuthenticated = computed(() => isLoggedIn.value && !!token.value)

  const expProgress = computed(() => {
    const currentLevelExp = Math.floor((userInfo.totalScore || 0) / 100) * 100
    const nextLevelExp = Math.floor((userInfo.totalScore || 0) / 100 + 1) * 100
    const progress = ((userInfo.totalScore || 0) - currentLevelExp) / (nextLevelExp - currentLevelExp) * 100
    return Math.min(100, Math.max(0, progress))
  })

  const nextLevelExp = computed(() => {
    return Math.floor((userInfo.totalScore || 0) / 100 + 1) * 100
  })

  // 方法
  /**
   * 设置 token
   * @param {string} newToken
   * @param {boolean} rememberMe 是否记住我
   */
  const setToken = (newToken, rememberMe = true) => {
    token.value = newToken
    if (newToken) {
      if (rememberMe) {
        localStorage.setItem('token', newToken)
        sessionStorage.removeItem('token')
      } else {
        sessionStorage.setItem('token', newToken)
        localStorage.removeItem('token')
      }
      // 先基于 token 的 claims 立即同步本地用户身份，避免显示历史持久化的模拟用户
      try { syncUserFromTokenClaims() } catch {}
      isLoggedIn.value = true
    } else {
      localStorage.removeItem('token')
      sessionStorage.removeItem('token')
      isLoggedIn.value = false
    }
  }

  const setUserInfo = (info) => {
    Object.assign(userInfo, info)
  }

  /**
   * 登录方法，需传入 rememberMe
   */
  const login = async (credentials, rememberMe = true) => {
    try {
      // 调用登录API
      const response = await authAPI.login(credentials)
      setToken(response.data.token, rememberMe)
      
      // 只在登录成功时设置用户信息，因为这是用户主动登录获取的最新数据
      if (response.data.user) {
        setUserInfo(response.data.user)
      }
      
      return response
    } catch (error) {
      throw error
    }
  }

  const logout = () => {
    setToken('')
    Object.assign(userInfo, {
      id: null,
      username: '',
      nickname: '',
      avatarUrl: '',
      email: '',
      status: 'offline',
      level: 1,
      experience: 0,
      totalGames: 0,
      winRate: 0,
      ranking: null,
      bestStreak: 0,
      joinDate: null
    })
  }

  const fetchUserInfo = async () => {
    try {
      // 如果没有token，直接返回
      if (!token.value) {
        throw new Error('未登录')
      }
      
      // 先验证token是否有效
      const verifyResponse = await authAPI.verifyToken()
      
      if (verifyResponse.code === 1000 && verifyResponse.data) {
        // 只更新登录状态，不覆盖本地存储的用户信息
        // 保留本地存储中真实的用户数据，只做token验证
        isLoggedIn.value = true
        
        // 如果本地userInfo的id为空，才使用后端返回的基本信息
        if (!userInfo.id) {
          setUserInfo({
            id: verifyResponse.data.id,
            username: verifyResponse.data.username,
            nickname: verifyResponse.data.nickname || verifyResponse.data.username,
            avatarUrl: verifyResponse.data.avatarUrl || '',
            status: verifyResponse.data.status || 'online',
            // 设置默认值
            email: '',
            level: 1,
            experience: 0,
            totalGames: 0,
            winRate: 0,
            ranking: null,
            bestStreak: 0,
            joinDate: verifyResponse.data.createdAt
          })
        }
        
        return verifyResponse.data
      } else {
        // token无效，清除登录状态
        logout()
        throw new Error(verifyResponse.message || '获取用户信息失败')
      }
    } catch (error) {
      console.error('获取用户信息失败:', error)
      // token无效时自动登出
      logout()
      throw error
    }
  }

  const updateUserInfo = async (updateData) => {
    try {
      const response = await userAPI.updateUserInfo(updateData)
      setUserInfo(response.data)
      return response
    } catch (error) {
      console.error('更新用户信息失败:', error)
      throw error
    }
  }

  const uploadAvatar = async (file) => {
    try {
      const formData = new FormData()
      formData.append('avatar', file)

      const response = await userAPI.uploadAvatar(formData)
      userInfo.avatar = response.data.url
      return response
    } catch (error) {
      console.error('上传头像失败:', error)
      throw error
    }
  }

  const changePassword = async (oldPassword, newPassword) => {
    try {
      const response = await userAPI.changePassword(oldPassword, newPassword)
      return response
    } catch (error) {
      console.error('修改密码失败:', error)
      throw error
    }
  }

  const updatePrivacySettings = async (settings) => {
    try {
      const response = await userAPI.updatePrivacySettings(settings)
      return response
    } catch (error) {
      console.error('更新隐私设置失败:', error)
      throw error
    }
  }

  // 初始化：如果有token，自动获取用户信息
  const init = async () => {
    token.value = getTokenFromStorage()
    if (token.value) {
      try {
        // 第一步：先从 token claims 立即同步本地身份，避免短时间内看到旧的模拟用户
        syncUserFromTokenClaims()
        
        // 第二步：验证token有效性，但不覆盖本地用户数据
        await fetchUserInfo()
        isLoggedIn.value = true
      } catch (error) {
        // 如果获取用户信息失败，清除token
        console.log('Token可能已过期，自动登出')
        logout()
      }
    }
  }

  return {
    // 状态
    isLoggedIn,
    token,
    userInfo,

    // 计算属性
    isAuthenticated,
    expProgress,
    nextLevelExp,

    // 方法
    setToken,
    setUserInfo,
    login,
    logout,
    fetchUserInfo,
    updateUserInfo,
    uploadAvatar,
    changePassword,
    updatePrivacySettings,
    init
  }
}, {
  persist: {
    key: 'user-store',
    storage: localStorage,
    paths: ['token'], // 只持久化 token，不持久化 userInfo
  }
})
